package com.jy.api.controller.clerk;

import com.jy.api.domain.*;
import com.jy.api.exception.MyException;
import com.jy.api.payReq.AllPayBaseResult;
import com.jy.api.service.*;
import com.jy.api.signUpReq.pos.PaymentSignUpReq;
import com.jy.api.signUpReq.web.WebCancelPayReq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.text.NumberFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 店员宝支付接口。使用{@link com.jy.api.controller.PaymentController}替代
 *
 * @deprecated 设计错误
 */
@Slf4j
@RestController
@RequestMapping(value = "v1/clerk", produces = "application/json;charset=utf-8")
public class ClerkPaymentController {
    private PaymentService paymentService;
    private OrderService orderService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private ProductService productService;
    @Autowired
    private CouponInstanceService couponInstanceService;

    /**
     * 订单支付
     *
     * @param paymentId
     * @param paymentSignUpReq
     * @return
     */
    @RequestMapping(method = RequestMethod.PUT, value = "/payments/{paymentId}")
    public ResponseEntity addPayments(@Valid @PathVariable(name = "paymentId") String paymentId,
                                      @RequestBody PaymentSignUpReq paymentSignUpReq,
                                      BindingResult bindingResult,
                                      HttpServletRequest request) throws Exception {

        try {
            log.info("订单号{},店员宝支付参数{}",paymentSignUpReq.getOrderId(),paymentSignUpReq);
            //保存订单的备注和座位号
            long value = redisTemplate.getExpire(paymentSignUpReq.getOrderId());
            if (value > 0) {
                return ResponseEntity.badRequest().body("请"+value+"秒后进行支付");
            }
            redisTemplate.opsForValue().set(paymentSignUpReq.getOrderId(), paymentSignUpReq.getOrderId(), 5, TimeUnit.SECONDS);
            Order switchOrder = orderService.findOne(paymentSignUpReq.getOrderId());
            String code = redisTemplate.opsForValue().get(switchOrder.getStoreId() + "switch");
            if (code != null && code.equals("TRUE")) {
                return ResponseEntity.badRequest().body("交班中，请等待交班完成后进行点单");
            }
            if (switchOrder.getType().equals(OrderType.SALES)) {
                List<String> strings = productService.judgeProductQty(switchOrder.getId());
                if (strings.size() > 0) {
                    return ResponseEntity.badRequest().body("订单中含有库存数量不足的商品，请移除后进行支付。");
                }
            }
            if (!switchOrder.getStatus().equals(OrderStatus.INIT) && !switchOrder.getStatus().equals(OrderStatus.CANCELED)) {
                log.warn("The status of order:{} is {}, micro pay is not allowed.", switchOrder.getId(), switchOrder.getStatus());
                return ResponseEntity.badRequest().body("订单当前状态不允许进行支付，请返回主页重新下单！");
            }

            if (switchOrder.getDiscount() < 0) {
                return ResponseEntity.badRequest().body("该订单异常，请移除商品后，重新点单");
            }

            if (switchOrder.getDiscount() == 0 && switchOrder.getAmount() != paymentSignUpReq.getAmount()) {
                return ResponseEntity.badRequest().body("该订单异常，请移除商品后，重新点单");
            }

            Map<String, Object> orderData = new HashMap<>();
            orderData.put("notes", paymentSignUpReq.getNotes());
            orderData.put("tableNo", paymentSignUpReq.getTableNo());
            orderService.patch(paymentSignUpReq.getOrderId(), orderData);
            if (paymentSignUpReq.getChannel().equals(PaymentChannel.PAYCARD)) {
                Order or = orderService.findOne(paymentSignUpReq.getOrderId());
                if (0 == or.getAmount()) {
                    return ResponseEntity.badRequest().body("点单金额为0元，不允许进行在线支付");
                }
                log.info("门店{} 订单号{} 内容{} 操作内容{}", or.getStoreId(), or.getId(), "支付开始", paymentSignUpReq);
                AllPayBaseResult result = paymentService.microPay(paymentSignUpReq.getOrderId(), paymentSignUpReq.getAuthCode());
                log.info("门店{} 订单号{} 内容{} 操作内容{}", or.getStoreId(), or.getId(), "支付结束", result);
                if (result.isSuccess()) {
                    log.info("订单号{},进入支付成功{}",paymentSignUpReq.getOrderId(),result.isSuccess());
                    Order order = orderService.findOne(paymentSignUpReq.getOrderId());
                    return ResponseEntity.ok().body(orderService.orderVoCouponInstance(order));
                } else if (result.isNeedQuery()) {
                    return ResponseEntity.accepted().build();
                } else if (result.isFailed()) {
                    return ResponseEntity.badRequest().body("交易失败");
                } else {
                    throw new RuntimeException("支付结果未知，请稍后到订单列表查看支付状态");
                }
            } else if (paymentSignUpReq.getChannel().equals(PaymentChannel.CASH) || paymentSignUpReq.getChannel().equals(PaymentChannel.ALIPAY_CASH) || paymentSignUpReq.getChannel().equals(PaymentChannel.WECHATPAY_CASH)) {
                try {
                    log.info("门店{} 订单号{} 内容{} 操作内容{}", switchOrder.getStoreId(), switchOrder.getId(), "支付开始", paymentSignUpReq);
                    paymentService.cashPay(paymentSignUpReq.getOrderId(), paymentSignUpReq.getAmount(), paymentSignUpReq.getChannel());
                    Order order = orderService.findOne(paymentSignUpReq.getOrderId());
                    return ResponseEntity.ok().body(orderService.orderVoCouponInstance(order));
                } catch (AmountNotMatchException e) {
                    return ResponseEntity.badRequest().body("支付金额与订单金额不匹配，请检查");
                }

            } else if (paymentSignUpReq.getChannel().equals(PaymentChannel.MEMBER)) {
                try {
                    log.info("门店{} 订单号{} 内容{} 操作内容{}", switchOrder.getStoreId(), switchOrder.getId(), "支付开始", paymentSignUpReq);
                    paymentService.memberPay(paymentSignUpReq.getOrderId(), paymentSignUpReq.getAmount());
                    Order order = orderService.findOne(paymentSignUpReq.getOrderId());
                    return ResponseEntity.ok().body(orderService.orderVoCouponInstance(order));
                } catch (MemberAccountNotEnoughException e) {
                    return ResponseEntity.badRequest().body("会员账户余额不足，请提醒顾客充值");
                } catch (AmountNotMatchException e) {
                    return ResponseEntity.badRequest().body("支付金额与订单金额不匹配，请检查");
                }
            } else {
                return ResponseEntity.badRequest().body("未识别的支付方式：" + paymentSignUpReq.getChannel());
            }
        } catch (Exception e) {
            log.info("exception{}", e);
            return ResponseEntity.badRequest().body("支付异常，" + e.getMessage());
        }


    }


    /**
     * 订单取消支付
     *
     * @param orderId
     * @return
     */
    @RequestMapping(method = RequestMethod.DELETE, value = "/payments/{orderId}")
    public ResponseEntity deletePay(@PathVariable String orderId) throws Exception {
        WebCancelPayReq req = new WebCancelPayReq();
        long value = redisTemplate.getExpire(orderId);
        if (value > 0) {
            return ResponseEntity.badRequest().body("取消支付失败，还剩余" + value + "秒可进行操作");
        }
        SwiftPassReversePaymentResult result = paymentService.cancelThirdPartyPayment(orderId, req);
        if (result.isSuccess()) {
            return ResponseEntity.ok().build();
        } else {
            return ResponseEntity.badRequest().body(result.getErrMsg());
        }
    }

    @Autowired
    public void setOrderService(OrderService orderService) {
        this.orderService = orderService;
    }

    @Autowired
    public void setPaymentService(PaymentService paymentService) {
        this.paymentService = paymentService;
    }
}

